1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.google.common.util.concurrent;
18
19 import com.google.caliper.BeforeExperiment;
20 import com.google.caliper.Benchmark;
21 import com.google.caliper.Param;
22
23 import java.util.concurrent.locks.Lock;
24 import java.util.concurrent.locks.ReentrantLock;
25
26
27
28
29
30
31 public class CycleDetectingLockFactoryBenchmark {
32
33 @Param({"2","3","4","5","10"}) int lockNestingDepth;
34
35 CycleDetectingLockFactory factory;
36 private Lock[] plainLocks;
37 private Lock[] detectingLocks;
38
39 @BeforeExperiment
40 void setUp() throws Exception {
41 this.factory = CycleDetectingLockFactory.newInstance(
42 CycleDetectingLockFactory.Policies.WARN);
43 this.plainLocks = new Lock[lockNestingDepth];
44 for (int i = 0; i < lockNestingDepth; i++) {
45 plainLocks[i] = new ReentrantLock();
46 }
47 this.detectingLocks = new Lock[lockNestingDepth];
48 for (int i = 0; i < lockNestingDepth; i++) {
49 detectingLocks[i] = factory.newReentrantLock("Lock" + i);
50 }
51 }
52
53 @Benchmark void unorderedPlainLocks(int reps) {
54 lockAndUnlock(new ReentrantLock(), reps);
55 }
56
57 @Benchmark void unorderedCycleDetectingLocks(int reps) {
58 lockAndUnlock(factory.newReentrantLock("foo"), reps);
59 }
60
61 private void lockAndUnlock(Lock lock, int reps) {
62 for (int i = 0; i < reps; i++) {
63 lock.lock();
64 lock.unlock();
65 }
66 }
67
68 @Benchmark void orderedPlainLocks(int reps) {
69 lockAndUnlockNested(plainLocks, reps);
70 }
71
72 @Benchmark void orderedCycleDetectingLocks(int reps) {
73 lockAndUnlockNested(detectingLocks, reps);
74 }
75
76 private void lockAndUnlockNested(Lock[] locks, int reps) {
77 for (int i = 0; i < reps; i++) {
78 for (int j = 0; j < locks.length; j++) {
79 locks[j].lock();
80 }
81 for (int j = locks.length - 1; j >= 0; j--) {
82 locks[j].unlock();
83 }
84 }
85 }
86 }